import struct,numpy as np

code2type = {0x08:'B',0x09:'b',0x0B:'h',0x0c:'i',0x0D:'f',0x0E:'d'}
type2code = {'uint8':0x08,'int8':0x09,'int16':0x0B,'int32':0x0C,'float32':0x0D,'float64':0x0E}

def createMatrix(low=0, high=1000, size=[30,4]):
    return np.random.uniform(low,high,size).astype('>f4')

def writeMatrix2(filename,matrix=createMatrix()):
    with open(filename,'wb') as f:
        shapes = matrix.shape
        fmt = '>HBB'
        fhead = struct.pack(fmt,0,type2code[matrix.dtype.name],len(shapes))
        f.write(fhead)
        fmt = '>{}I'.format(len(shapes))
        fhead = struct.pack(fmt,*shapes)
        f.write(fhead)
        f.write(matrix)

def readMatrix(filename):
    with open(filename,'rb') as f:
        buff = f.read()
        offset = 0
        fmt = '>HBB'
        _,dcode,dimslen = struct.unpack_from(fmt,buff,offset)
        offset += struct.calcsize(fmt)

        fmt = '>{}I'.format(dimslen)
        shapes = struct.unpack_from(fmt,buff,offset)
        offset += struct.calcsize(fmt)

        fmt = '>'+ str(np.prod(shapes)) + code2type[dcode]
        matrix = struct.unpack_from(fmt,buff,offset)
        matrix = np.reshape(matrix,shapes).astype(code2type[dcode])
        print(type(matrix),matrix.dtype,matrix)

    return matrix

# writeMatrix2('matrix')
readMatrix('matrix')